/*

Copyright 2009 Nicola Dal Pont

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Version ${MAJOR_VERSION}.${MINOR_VERSION}${BETA_MARK} Build ${BUILD_NUMBER}

*/

package com.astoolkit.xmlmapping
{
   import flash.utils.Dictionary;
   import flash.utils.flash_proxy;
   
   import mx.utils.ObjectProxy;
   
   use namespace flash_proxy;
   public dynamic class XmlMappingContext  extends ObjectProxy
   {

      XMLMAPPING_PRIVATE var mappedProperties : Dictionary = new Dictionary( true );
      XMLMAPPING_PRIVATE var mappingsStack : Array = [];  
      
      XMLMAPPING_PRIVATE function init( mapping : XmlMapping ) : void
      {
         XMLMAPPING_PRIVATE::mappingsStack.unshift( new MappingInfo() );
      }

      XMLMAPPING_PRIVATE function cleanUp() : void
      {
         var mappingInfo : MappingInfo = MappingInfo( XMLMAPPING_PRIVATE::mappingsStack.shift() );
         //var currentMappingProperties : Array = XMLMAPPING_PRIVATE::mappingsStack.shift();
         while( mappingInfo.properties.length > 0 )
         {
            delete XMLMAPPING_PRIVATE::mappedProperties[ 
               mappingInfo.properties.pop()
               ]; 
         }
      }
      
      XMLMAPPING_PRIVATE function propertyMapped( property : MapProperty, value : * ) : void
      {
         MappingInfo(XMLMAPPING_PRIVATE::mappingsStack[0] ).properties.push( property );
         XMLMAPPING_PRIVATE::mappedProperties[ property ] = value;
      } 
      
      XMLMAPPING_PRIVATE function setVariable( name : String, value : * ) : void
      {
         MappingInfo(XMLMAPPING_PRIVATE::mappingsStack[0] ).variables[ name ] = value;
      } 
      
      /**
      * Gives access an already-parsed property's value.
      * Useful to perform cross-property contitional mapping.
      */
      public function getPropertyValue( property : MapProperty ) : *
      {
         if( XMLMAPPING_PRIVATE::mappedProperties[ property ] == null )
         {
            //TODO: wrap this nicely in XmlMapping errors handling
            throw new Error("attempt to access an unmapped property: early referencing?");
         }
         return XMLMAPPING_PRIVATE::mappedProperties[ property ];
      }

      flash_proxy override function getProperty( name : *) : *
      {
         if( String( name ).match(/^\$\w+/) )
         {
            var mappingInfo : MappingInfo = MappingInfo( XMLMAPPING_PRIVATE::mappingsStack[ 0 ] );
            if( mappingInfo.variables.hasOwnProperty( String( name ).substr( 1 ) ) )
            {
               return mappingInfo.variables[ String( name ).substr( 1 ) ];
            }
         }
         return null;
      }
   }
}
import flash.utils.Dictionary;
   
class MappingInfo 
{
  public var variables : Dictionary = new Dictionary();
  public var properties : Array = [];
}
